<?php
/**
 ***********************************************************************************************************************
 * 辅助/快捷函数
 ***********************************************************************************************************************
 */


/**
 * 随机字母+数字+大小写
 */
function randomString($length = 6) {
//    $characters='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
//    $charactersLength = strlen($characters);
//    $randomString = '';
//    for ($i = 0; $i < $length; $i++) {
//        $randomString .= $characters[rand(0, $charactersLength - 1)];
//    }
//    return $randomString;
    return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}

/**
 * 打印调试
 * @param string $var
 * @param bool $flag
 */
function myprint($var = '', $flag = false)
{
    header("Content-type: text/html; charset=utf-8");
    echo '<pre>';
    $flag === true ? var_dump($var) : ($flag === 0 ? var_export($var) : print_r($var));
    exit;
}


/**
 * var_dump格式化调试工具,支持console模式
 *
 * @param $input
 * @param bool $collapse
 */
function dumpDebug($input, $collapse = false)
{
    $recursive = function($data, $level=0) use (&$recursive, $collapse) {
        global $argv;
        $isTerminal = isset($argv);
        if (!$isTerminal && $level == 0 && !defined("DUMP_DEBUG_SCRIPT")) {
            define("DUMP_DEBUG_SCRIPT", true);
            echo '<script language="Javascript">function toggleDisplay(id) {';
            echo 'var state = document.getElementById("container"+id).style.display;';
            echo 'document.getElementById("container"+id).style.display = state == "inline" ? "none" : "inline";';
            echo 'document.getElementById("plus"+id).style.display = state == "inline" ? "inline" : "none";';
            echo '}</script>'."\n";
        }
        $type = !is_string($data) && is_callable($data) ? "Callable" : ucfirst(gettype($data));
        $type_data = null;
        $type_color = null;
        $type_length = null;
        switch ($type) {
            case "String":
                $type_color = "green";
                $type_length = strlen($data);
                $type_data = "\"" . htmlentities($data) . "\""; break;
            case "Double":
            case "Float":
                $type = "Float";
                $type_color = "#0099c5";
                $type_length = strlen($data);
                $type_data = htmlentities($data); break;
            case "Integer":
                $type_color = "red";
                $type_length = strlen($data);
                $type_data = htmlentities($data); break;
            case "Boolean":
                $type_color = "#92008d";
                $type_length = strlen($data);
                $type_data = $data ? "TRUE" : "FALSE"; break;
            case "NULL":
                $type_length = 0; break;
            case "Array":
                $type_length = count($data);
        }
        if (in_array($type, array("Object", "Array"))) {
            $notEmpty = false;
            foreach($data as $key => $value) {
                if (!$notEmpty) {
                    $notEmpty = true;
                    if ($isTerminal) {
                        echo $type . ($type_length !== null ? "(" . $type_length . ")" : "")."\n";
                    } else {
                        $id = substr(md5(rand().":".$key.":".$level), 0, 8);
                        echo "<a href=\"javascript:toggleDisplay('". $id ."');\" style=\"text-decoration:none\">";
                        echo "<span style='color:#666666'>" . $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "</span>";
                        echo "</a>";
                        echo "<span id=\"plus". $id ."\" style=\"display: " . ($collapse ? "inline" : "none") . ";\">&nbsp;&#10549;</span>";
                        echo "<div id=\"container". $id ."\" style=\"display: " . ($collapse ? "" : "inline") . ";\">";
                        echo "<br />";
                    }
                    for ($i=0; $i <= $level; $i++) {
                        echo $isTerminal ? "|    " : "<span style='color:black'>|</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                    }
                    echo $isTerminal ? "\n" : "<br />";
                }
                for ($i=0; $i <= $level; $i++) {
                    echo $isTerminal ? "|    " : "<span style='color:black'>|</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                }
                echo $isTerminal ? "[" . $key . "] => " : "<span style='color:black'>[" . $key . "]&nbsp;=>&nbsp;</span>";
                call_user_func($recursive, $value, $level+1);
            }
            if ($notEmpty) {
                for ($i=0; $i <= $level; $i++) {
                    echo $isTerminal ? "|    " : "<span style='color:black'>|</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                }
                if (!$isTerminal) {
                    echo "</div>";
                }
            } else {
                echo $isTerminal ?
                    $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "  " :
                    "<span style='color:#666666'>" . $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "</span>&nbsp;&nbsp;";
            }
        } else {
            echo $isTerminal ?
                $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "  " :
                "<span style='color:#666666'>" . $type . ($type_length !== null ? "(" . $type_length . ")" : "") . "</span>&nbsp;&nbsp;";

            if ($type_data != null) {
                echo $isTerminal ? $type_data : "<span style='color:" . $type_color . "'>" . $type_data . "</span>";
            }
        }
        echo $isTerminal ? "\n" : "<br />";
    };
    call_user_func($recursive, $input);
}


/**
 ***********************************************************************************************************************
 * 系统快捷函数
 ***********************************************************************************************************************
 */

use artisan\config;
use artisan\input;
use artisan\logger\logger;
use artisan\output;
use artisan\url;

/**
 * 获取配置文件内容
 *
 * @param string $file
 * @param string $key
 * @return mixed
 */
function config($file, $key = '')
{
    return config::get($file, $key);
}

/**
 * 获取全局配置文件内容
 *
 * @param string $key
 * @return config|mixed|null
 */
function globalConfig($key = '')
{
    return config('global', $key);
}

/**
 * 获取当前系统环境
 *
 * @return string
 */
function env()
{
    return globalConfig('debug') ? 'develop' : 'product';
}

/**
 * 系统(项目)名称 日志追踪方便使用 一般项目可以不设置
 *
 * @return string
 */
function project()
{
    return globalConfig('project') ?: '';
}

/**
 * 系统输出内容格式(暂时支持json/xml格式的restful接口，和html格式的网站) 兼容旧版
 *
 * @return string
 */
function outputFormat()
{
    $format = ((defined('RESTFUL') && RESTFUL === true) || input::isAjax()) ? 'text/json' : (globalConfig('output.format') ?:'text/html');
    // 支持新版
    return in_array(\artisan\artisan::$output_format, ['text/json', 'text/html', 'text/xml']) ? \artisan\artisan::$output_format : $format;
}

/**
 * 注册一个请求结束后执行事件
 * @param callable|Closure $event
 */
function later(\Closure $event)
{
    output::later($event);
}


/**
 ***********************************************************************************************************************
 * 系统输出函数
 ***********************************************************************************************************************
 */

/**
 * 获取编译后的模板视图内容
 *
 * @param string $template
 * @param array $templateData
 * @return string
 */
function view($template = '', array $templateData = [])
{
    return output::getTemplateContent($template, $templateData);
}

/**
 * 获取编译后的模板视图内容
 *
 * @param string $template
 * @param array $templateData
 * @return string
 */
function viewContent($template = '', array $templateData = [])
{
    return view($template, $templateData);
}

/**
 * 动态设置模板
 *
 * @param string $template                 示例：mytemplate_dir/mytemplate
 * @param array $templateData              示例：['var' => 'hello world']
 */
function template($template = '', array $templateData = [])
{
    output::setTemplate($template, $templateData);
}

/**
 * 动态设置布局
 *
 * @param string $layout
 * @param array $layoutData
 */
function layout($layout = '', array $layoutData = [])
{
    output::setLayout($layout, $layoutData);
}

/**
 * 抛出错误 兼容任何输出格式内容
 *
 * @param int $code
 * @param string $msg
 * @param mixed $data
 * @return bool
 */
function raise($code = 404, $msg = '', $data = [])
{
    // 兼容数组方式写法
    if(is_array($code)) {
        foreach (['code', 'msg', 'data'] as $item)
        {
            if (isset($code[$item]))
            {
                $$item = $code[$item];
            }
        }
    }
    output::raise($code, $msg, $data);
    return true;
}

/**
 * @return bool
 */
function keep()
{
    $funcArgs = func_get_args();
    $closure = end($funcArgs);

    // 注册结束事件
    if($closure instanceof \Closure) {
        later($closure);
        array_pop($funcArgs);
    }

    // 设置输出内容
    $data = [];
    if(isset($funcArgs[0])) {
        output::setData($funcArgs[0]);
    }

    // 设置输出错误消息
    if(isset($funcArgs[1])) {
        output::setErrorMsg(abs(intval($funcArgs[1])));
    }
    // 输出内容
    output::flush($data);
    return true;
}

/**
 * 直接跳转 兼容ajax
 *
 * @param string $url
 * @param int $http_code
 */
function redirect($url = '', $http_code = 302)
{
    if(input::isAjax()) {
        raise(302, '请求重定向', $url);
    }
    output::redirect($url, $http_code);
}

/**
 * 跳转提示 兼容ajax
 *
 * @param string $url
 * @param string $msg
 * @param int $delay
 */
function alert($url = '', $msg = '提示信息', $delay = 2)
{
    if(input::isAjax()) {
        raise(302, $msg, $url);
    }
    exit(view('alert/alert', ['url' => $url, 'msg' => $msg, 'delay' => $delay]));
}


/**
 ***********************************************************************************************************************
 * 系统日志函数
 ***********************************************************************************************************************
 */

/**
 * @param $message
 * @param string $breakpoint
 * @param string|bool $service_name
 * @param string $service_name
 * @param bool $isRecordAll
 * @return bool
 */
function logDebug($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::DEBUG, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logInfo($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::INFO, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logError($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::ERROR, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logAlert($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::ALERT, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logWarning($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::WARNING, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logNotice($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::NOTICE, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logEmergency($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::EMERGENCY, $message, [], $breakpoint, $service_name,$isRecordAll);
}

/**
 * @param $message
 * @param string $breakpoint
 * @param string $service_name
 * @return bool
 */
function logCritical($message, $breakpoint = '', $service_name = '',$isRecordAll=false)
{
    return logger::add(logger::CRITICAL, $message, [], $breakpoint, $service_name,$isRecordAll);
}


/**
 ***********************************************************************************************************************
 * 系统url函数
 ***********************************************************************************************************************
 */

/**
 * @param $url
 * @return string
 */
function url($url = '')
{
    return url::base($url);
}

/**
 * @param $url
 * @return string
 */
function baseUrl($url = '')
{
    return url::base($url);
}

/**
 * @return string
 */
function siteUrl()
{
    return baseUrl();
}

/**
 * @return string
 */
function currentUrl()
{
    return url::current();
}

/**
 * @param $url
 * @return string
 */
function staticUrl($url = '')
{
    return url::statics($url);
}

/**
 * @param $url
 * @return string
 */
function uploadUrl($url = '')
{
    return url::upload($url);
}

/**
 * @param $url
 * @return string
 */
function jsUrl($url = '')
{
    return url::js($url);
}

/**
 * @param $url
 * @return string
 */
function cssUrl($url = '')
{
    return url::css($url);
}

/**
 * @param $url
 * @return string
 */
function imgUrl($url = '')
{
    return url::img($url);
}


/**
 ***********************************************************************************************************************
 * 服务 异常捕获
 ***********************************************************************************************************************
 */
if(class_exists('\soa\client')) {
    /**
     * @return int
     */
    function last_srv_code()
    {
        return \soa\client::$_code;
    }

    /**
     * @return string
     */
    function last_srv_msg()
    {
        return \soa\client::$_msg;
    }

    /**
     * @return int
     */
    function last_srv_error()
    {
        return \soa\client::$_error;
    }

    /**
     * @return mixed
     */
    function last_srv_result()
    {
        return \soa\client::$_result;
    }

    /**
     * @return mixed
     */
    function last_srv_data()
    {
        return \soa\client::$_data;
    }

    /**
     * 抛出错误
     */
    function if_error_then_raise()
    {
        if (last_srv_error() != 0) {
            raise(last_srv_code(), last_srv_msg());
        }
    }


    /**
     * 抛出异常
     * @throws Exception
     */
    function if_exception_then_throw()
    {
        if (last_srv_error() != 0) {
            throw new \Exception(last_srv_msg(), last_srv_code());
        }
    }

    /**
     * 记录错误
     * @param string $break_point
     */
    function if_error_then_log($break_point = '')
    {
        if (last_srv_error() != 0) {
            logDebug('An error occurred, code: ' . last_srv_code() . ', message: ' . last_srv_msg(), $break_point);
        }
    }

    /**
     * 记录失败
     * @param $result
     * @param string $break_point
     * @param string $message
     */
    function if_false_then_log($result, $break_point = '', $message = '')
    {
        if (!$result) {
            logDebug('Execution failed' . ($message ? ': ' . $message : ''), $break_point);
        }
    }

    /**
     *检查字符串是否被序列号过
     * @param	string	$value	Value to test for serialized form
     * @param	mixed	$result	Result of unserialize() of the $value
     * @return	boolean			True if $value is serialized data, otherwise FALSE
     */
    function is_serialized($value, &$result = null){
        // Bit of a give away this one
        if (!is_string($value))
        {
            return false;
        }
        // Serialized false, return true. unserialize() returns false on an
        // invalid string or it could return false if the string is serialized
        // false, eliminate that possibility.
        if ($value === 'b:0;')
        {
            $result = false;
            return true;
        }
        $length	= strlen($value);
        $end	= '';
        switch ($value[0])
        {
            case 's':
                if ($value[$length - 2] !== '"')
                {
                    return false;
                }
            case 'b':
            case 'i':
            case 'd':
                // This looks odd but it is quicker than isset()ing
                $end .= ';';
            case 'a':
            case 'O':
                $end .= '}';
                if ($value[1] !== ':')
                {
                    return false;
                }
                switch ($value[2])
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                    case 8:
                    case 9:
                        break;
                    default:
                        return false;
                }
            case 'N':
                $end .= ';';
                if ($value[$length - 1] !== $end[0])
                {
                    return false;
                }
                break;
            default:
                return false;
        }
        if (($result = @unserialize($value)) === false)
        {
            $result = null;
            return false;
        }
        return true;
    }
}

/**
 * 判断本地环境是否为无效环境
 * 为方便做服务器迁移使用
 * add by lss
 * @return bool
 */
function isDisableEnv(){
    return false;
//    return soa\check\EnvCheck::isEnvVPC();
}

function get_code($code) {
    return config('code', $code);
}